﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="MatchmakingPartnerActioner.cs" company="DissingNelleman">
//   
// All rights reserved. </copyright>
// <summary>
//   The matchmaking partner actioner.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace ServiceLibrary.Actioners.Activities
{
    using System;
    using System.Collections.Generic;
    using System.Linq;

    using NHibernate;

    using ServiceLibrary.Models.Domain;
    using ServiceLibrary.Services.Commands;
    using ServiceLibrary.Services.Queries;
    using ServiceLibrary.Services.Results;

    /// <summary>
    /// The matchmaking partner actioner.
    /// </summary>
    internal class MatchmakingPartnerActioner : ActionerBase
    {
        #region Constructors and Destructors

        /// <summary>
        /// Initializes a new instance of the <see cref="MatchmakingPartnerActioner"/> class.
        /// </summary>
        /// <param name="session">
        /// The session.
        /// </param>
        /// <param name="activeUser">
        /// The active user.
        /// </param>
        public MatchmakingPartnerActioner(ISession session, User activeUser)
            : base(session, activeUser)
        {
        }

        #endregion

        #region Public Methods and Operators

        /// <summary>
        /// The create matchmaking partner.
        /// </summary>
        /// <param name="obj">
        /// The obj.
        /// </param>
        /// <returns>
        /// The <see cref="Guid"/>.
        /// </returns>
        public Guid CreateMatchmakingPartner(MatchmakingPartner obj)
        {
            obj.CreatedDateTime = DateTime.Now;
            this.Session.Save(obj);

            // log.CreateLogEntry(obj.ID, "objekt '{0}' blev oprettet.", Models.Base.LogEntryType.MatchmakingPartner);
            return obj.ID;
        }

        /// <summary>
        /// The create matchmaking partner.
        /// </summary>
        /// <param name="cmd">
        /// The cmd.
        /// </param>
        public void CreateMatchmakingPartner(CreateMatchmakingPartnerCommand cmd)
        {
            if (cmd.NewMatchmakingPartner != null)
            {
                var obj = new MatchmakingPartner
                              {
                                  ID = cmd.NewMatchmakingPartner.ID, 
                                  Type =
                                      this.Session.Get<MatchmakingPartnerType>(
                                          cmd.NewMatchmakingPartner.Type), 
                                  OtherText = cmd.NewMatchmakingPartner.OtherText, 
                                  ProductDevelopmentText =
                                      cmd.NewMatchmakingPartner.ProductDevelopmentText, 
                                  SalesText = cmd.NewMatchmakingPartner.SalesText, 
                                  TestText = cmd.NewMatchmakingPartner.TestText
                              };
                CreateMatchmakingPartner(obj);
            }
        }

        /// <summary>
        /// The execute search query.
        /// </summary>
        /// <param name="matchmakingPartnerQuery">
        /// The matchmaking partner query.
        /// </param>
        /// <returns>
        /// The <see cref="IResult"/>.
        /// </returns>
        public IResult ExecuteSearchQuery(MatchmakingPartnerQuery matchmakingPartnerQuery)
        {
            SearchSettings settings = matchmakingPartnerQuery.Settings;
            var result = new MatchmakingPartnerResult();

            IQueryOver<MatchmakingPartner, MatchmakingPartner> search = this.Session.QueryOver<MatchmakingPartner>();
            this.ApplyDefaultCriterias(matchmakingPartnerQuery.Settings, search);

            result.TotalRowCount = search.RowCount();
            IList<MatchmakingPartner> list = ApplySkipAndTake(settings, search);

            if (list.Any())
            {
                list = list.OrderBy(x => x.Type.Name).ToList();
                foreach (MatchmakingPartner matchmakingPartner in list)
                {
                    result.List.Add(Services.Dto.MatchmakingPartner.Convert(matchmakingPartner));
                }
            }

            return result;
        }

        #endregion

        #region Methods

        /// <summary>
        /// The create matchmaking partner related objects.
        /// </summary>
        internal void CreateMatchmakingPartnerRelatedObjects()
        {
            IList<MatchmakingPartnerType> partnerTypes = this.Session.QueryOver<MatchmakingPartnerType>().List();
            var konsortie = new MatchmakingPartnerType
                                {
                                    ID = Guid.NewGuid(), 
                                    Name = "Konsortie", 
                                    ShowOtherText = true, 
                                    ShowProductDevelopmentText = true, 
                                    ShowSalesText = true, 
                                    ShowTestText = true
                                };
            var b2B = new MatchmakingPartnerType
                          {
                              ID = Guid.NewGuid(), 
                              Name = "B2B", 
                              ShowOtherText = true, 
                              ShowProductDevelopmentText = true, 
                              ShowSalesText = false, 
                              ShowTestText = true
                          };
            var opi = new MatchmakingPartnerType
                          {
                              ID = Guid.NewGuid(), 
                              Name = "OPI", 
                              ShowOtherText = true, 
                              ShowProductDevelopmentText = true, 
                              ShowSalesText = false, 
                              ShowTestText = true
                          };
            var klynge = new MatchmakingPartnerType
                             {
                                 ID = Guid.NewGuid(), 
                                 Name = "Klynge", 
                                 ShowOtherText = true, 
                                 ShowProductDevelopmentText = false, 
                                 ShowSalesText = false, 
                                 ShowTestText = false
                             };
            var andet = new MatchmakingPartnerType
                            {
                                ID = Guid.NewGuid(), 
                                Name = "Andet", 
                                ShowOtherText = true, 
                                ShowProductDevelopmentText = false, 
                                ShowSalesText = false, 
                                ShowTestText = false
                            };
            var defaultPartnerTypes = new List<MatchmakingPartnerType> { konsortie, b2B, opi, klynge, andet };
            foreach (var type in from type in defaultPartnerTypes let alreadyExists = (from t in partnerTypes where t.Name.Equals(type.Name) select t).Any() where !alreadyExists select type)
            {
                this.Session.Save(type);
            }
        }

        /// <summary>
        /// The create matchmaking partner type.
        /// </summary>
        /// <param name="cmd">
        /// The cmd.
        /// </param>
        internal void CreateMatchmakingPartnerType(CreateMatchmakingPartnerTypeCommand cmd)
        {
            if (cmd.NewMatchmakingPartnerType != null)
            {
                var type = new MatchmakingPartnerType
                               {
                                   ID = cmd.NewMatchmakingPartnerType.ID, 
                                   Name = cmd.NewMatchmakingPartnerType.Name, 
                                   ShowOtherText = cmd.NewMatchmakingPartnerType.ShowOtherText, 
                                   ShowProductDevelopmentText =
                                       cmd.NewMatchmakingPartnerType.ShowProductDevelopmentText, 
                                   ShowSalesText = cmd.NewMatchmakingPartnerType.ShowSalesText, 
                                   ShowTestText = cmd.NewMatchmakingPartnerType.ShowTestText
                               };

                this.Session.Save(type);
            }
        }

        /// <summary>
        /// The delete matchmaking partner.
        /// </summary>
        /// <param name="cmd">
        /// The cmd.
        /// </param>
        internal void DeleteMatchmakingPartner(DeleteMatchmakingPartnerCommand cmd)
        {
            var partner = this.Session.Get<MatchmakingPartner>(cmd.Dto);

            if (partner != null)
            {
                int partnerUsage =
                    this.Session.QueryOver<Matchmaking>().Where(x => x.Partners.Contains(partner)).RowCount();
                if (partnerUsage == 0)
                {
                    this.Session.Delete(partner);
                }
            }
        }

        /// <summary>
        /// The query all partner types.
        /// </summary>
        /// <param name="matchmakingPartnerTypeQuery">
        /// The matchmaking partner type query.
        /// </param>
        /// <returns>
        /// The <see cref="IResult"/>.
        /// </returns>
        internal IResult QueryAllPartnerTypes(MatchmakingPartnerTypeQuery matchmakingPartnerTypeQuery)
        {
            var result = new MatchmakingPartnerTypeResult();

            var list = this.Session.QueryOver<MatchmakingPartnerType>().List().OrderBy(x => x.Name);
            result.TotalRowCount = list.Count();

            foreach (MatchmakingPartnerType type in list)
            {
                result.List.Add(Services.Dto.MatchmakingPartnerType.Convert(type));
            }

            return result;
        }

        /// <summary>
        /// The update matchmaking partner.
        /// </summary>
        /// <param name="cmd">
        /// The cmd.
        /// </param>
        internal void UpdateMatchmakingPartner(UpdateMatchmakingPartnerCommand cmd)
        {
            if (cmd.Dto != null)
            {
                var partner = this.Session.Get<MatchmakingPartner>(cmd.Dto.ID);
                if (partner != null)
                {
                    partner.OtherText = cmd.Dto.OtherText;
                    partner.ProductDevelopmentText = cmd.Dto.ProductDevelopmentText;
                    partner.SalesText = cmd.Dto.SalesText;
                    partner.TestText = cmd.Dto.TestText;
                    partner.Type = this.Session.Get<MatchmakingPartnerType>(cmd.Dto.Type);

                    this.Session.Update(partner);
                }
            }
        }

        #endregion
    }
}